package com.markyao.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.markyao.dao.dos.Archives;
import com.markyao.dao.mapper.ArticlBodyMapper;
import com.markyao.dao.mapper.ArticleMapper;
import com.markyao.dao.mapper.TagMapper;
import com.markyao.dao.pojo.AriticleBody;
import com.markyao.dao.pojo.Article;
import com.markyao.dao.pojo.ArticleTag;
import com.markyao.dao.pojo.SysUser;
import com.markyao.service.*;
import com.markyao.utils.UserThreadLocal;
import com.markyao.vo.ArticleBodyVo;
import com.markyao.vo.ArticleVo;
import com.markyao.vo.TagVo;
import com.markyao.vo.parmas.ArticleBodyParam;
import com.markyao.vo.parmas.ArticleParmas;
import com.markyao.vo.parmas.PageParmas;
import com.markyao.vo.Result;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.fasterxml.jackson.databind.type.LogicalType.DateTime;

@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private TagServiceImpl tagService;
    @Autowired
    private SysUserServiceImpl sysUserService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private ArticleBodyServcie articleBodyServcie;

    @Override
    public Result listArticle(PageParmas pageParmas) {
        List<Article> articlePage=new ArrayList<>();
        if(pageParmas.getCategoryId()!=null){
            PageHelper.startPage(pageParmas.getPage(), pageParmas.getPageSize());
            //根据文章分类id查询
            articlePage=articleMapper.findArticleByCid(pageParmas.getCategoryId());
        }
        else if(pageParmas.getTagId()!=null){
            //根据文章标签id查询;注意查询的是中间表
            List<Long> aids = articleTagService.findAidsByTId(pageParmas.getTagId());//先查中间表里所有的文章id,将这个id结果集用来查询文章
            System.out.println("-------------查询Aids?"+aids);
            if(aids.size()!=0&&aids!=null){
                PageHelper.startPage(pageParmas.getPage(), pageParmas.getPageSize());
                articlePage=articleMapper.findArticleByTagId(aids);
            }
        }
        else if(pageParmas.getYear()!=null && pageParmas.getMonth()!=null){
            //根据年月归档查询
            PageHelper.startPage(pageParmas.getPage(), pageParmas.getPageSize());
            articlePage=articleMapper.findArticleByYearAndMonth(pageParmas.getYear(),pageParmas.getMonth());
        }
        else if(pageParmas.getQueryString()!=null&&pageParmas.getQueryString().length()>0){
            //模糊查询
            PageHelper.startPage(pageParmas.getPage(), pageParmas.getPageSize());
            articlePage=articleMapper.findArticleByQuery(pageParmas.getQueryString());
            System.out.println("走模糊查询...");
        }
        else {
            PageHelper.startPage(pageParmas.getPage(), pageParmas.getPageSize());
            articlePage = articleMapper.findArticlePage();
        }
        PageInfo pageInfo=new PageInfo(articlePage);
        int total_pages = pageInfo.getPages();
        List<ArticleVo>articleVoList=copyList(articlePage,true,true);
        //分页查询文章列表

        return Result.success(articleVoList,total_pages);
    }

    @Override
    public Result hotArticle(int limit) {
        List<Article>hotArticle=articleMapper.findHotArticle(limit);

        return Result.success(copyList(hotArticle,false,true));
    }

    @Override
    public Result newArticle(int limit) {
        List<Article>newArticle=articleMapper.findNewArticle(limit);

        return Result.success(copyList(newArticle,false,true));
    }

    @Override
    public Result listArchives() {
        List<Archives> listArchives=articleMapper.listArchives();
        return Result.success(listArchives);
    }

    @Autowired
    ThreadService threadService;
    @Override
    public Result findArticleById(Long id) {
        /*
        body_id
        category_id
        文章详情
         */
        Article article=articleMapper.findArticleById(id);
        ArticleVo articleVo=copy(article,true,true,true,true);
        //阅读数需要更新，使用线程池就不会影响到主线程的使用
        threadService.updateViewCounts(articleMapper,article);
        return Result.success(articleVo);
    }

    @Autowired
    ArticleTagService articleTagService;
    @Override
    public Result publish(ArticleParmas articleParmas) {
        /*
        发布文章——构建article对象
        1.作者id
        2.文章id
        3.body id
         */
        SysUser sysUser = UserThreadLocal.get();//通过threadLocal获取
        Article article=new Article();
        article.setAuthorId(sysUser.getId());//得到作者id
        article.setCreateDate(System.currentTimeMillis());
        article.setWeight(Article.Article_Common);
        article.setSummary(articleParmas.getSummary());
        article.setTitle(articleParmas.getTitle());
        article.setViewCounts(0);
        article.setCommentCounts(0);
        article.setCategoryId(Long.parseLong(articleParmas.getCategory().getId()));
        article.setSummaryImg(articleParmas.getSummaryImg());
        this.articleMapper.insertArticle(article);
        Long articleId = article.getId();//得到文章id
        //插入body表得到bodyid
        ArticleBodyParam body = articleParmas.getBody();
        AriticleBody ariticleBody=new AriticleBody();
        ariticleBody.setArticleId(articleId);
        ariticleBody.setContent(body.getContent());
        ariticleBody.setContent_html(body.getContentHtml());
        this.articleBodyServcie.insert(ariticleBody);
        Long bodyId = ariticleBody.getId();//得到bodyId
        article.setBodyId(bodyId);//得到bodyId之后还要更新一下
        this.articleMapper.update(article);

        //插入article_tag表
        List<TagVo> tags = articleParmas.getTags();
        for (TagVo tag : tags) {
            ArticleTag articleTag=new ArticleTag();
            articleTag.setArticleId(articleId);
            articleTag.setTagId(Long.parseLong(tag.getId()));
            this.articleTagService.insert(articleTag);
        }
        Map<String,String>map=new HashMap<>();
        map.put("id",articleId.toString());

        return Result.success(map);
    }

    @Override
    public Long findUidByAid(Long articleId) {
        return articleMapper.findUidByAid(articleId);
    }

    @Override
    public String findTitleById(Long articleId) {
        return articleMapper.findTitleById(articleId);
    }

    private List<ArticleVo> copyList(List<Article> articlePage,boolean isTag,boolean isAuthor) {
        List<ArticleVo> articleVoList=new ArrayList<>();
        //转移
        for (Article article : articlePage) {
            ArticleVo copy = copy(article,isTag,isAuthor,false,false);
            articleVoList.add(copy);
        }
        return articleVoList;
    }


    //不是所有接口都需要标签和作者信息
    private ArticleVo copy(Article article,boolean isTag,boolean isAuthor,boolean isBody,boolean isCategory){
        ArticleVo articleVo=new ArticleVo();
        articleVo.setId(String.valueOf(article.getId()));//转化为string
        BeanUtils.copyProperties(article,articleVo);

        articleVo.setSummaryImg(article.getSummaryImg());
        articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));
        if(isTag){
            articleVo.setTags(tagService.findTahsByArticleId(article.getId()));
        }
        if(isAuthor){
            articleVo.setAuthor(sysUserService.findSysUserByArticleId(article.getId()));
        }
        if(isBody){
            Long bId=article.getBodyId();
            articleVo.setBody(findBodyById(bId));
        }
        if(isCategory){
            Long categoryId = article.getCategoryId();
            articleVo.setCategory(categoryService.findCategoryVoById(categoryId));
        }
        return articleVo;
    }

    @Autowired
    ArticlBodyMapper articlBodyMapper;
    private ArticleBodyVo findBodyById(Long bId) {
        AriticleBody ariticleBody=articlBodyMapper.findBodyByBId(bId);
        ArticleBodyVo ariticleBodyVo=new ArticleBodyVo();
        ariticleBodyVo.setContent(ariticleBody.getContent());
        return ariticleBodyVo;
    }


}
